from typing import Any

from aiogram import Bot, types
from aiogram_dialog import Dialog, DialogManager, Window
from aiogram_dialog.widgets.input import TextInput
from aiogram_dialog.widgets.kbd import Back, Button, Cancel, Group
from apscheduler.schedulers.asyncio import AsyncIOScheduler

from app.bot.dialog.dialog_states import IpChangePeriodSG
from app.bot.dialog.widgets import LocaleText
from app.bot.services.locale import Locale
from app.bot.services.loggers import logger
from app.bot.services.scheduler import jobs
from app.config import Settings


async def select_custom_period(
    call: types.CallbackQuery, widget: Any, manager: DialogManager
):
    await manager.switch_to(IpChangePeriodSG.select_custom_period)


async def set_ip_change_period(
    call: types.CallbackQuery,
    widget: Any,
    manager: DialogManager,
    custom_period: str = None,
):
    if custom_period:
        rotation_period = int(custom_period)
    else:
        rotation_period = int(widget.widget_id)

    if rotation_period == 0:
        reload_type = "by_link"
    else:
        reload_type = "by_time"

    locale: Locale = manager.middleware_data.get("locale")
    scheduler: AsyncIOScheduler = manager.middleware_data.get("scheduler")
    bot: Bot = manager.middleware_data.get("bot")
    config: Settings = manager.middleware_data.get("config")
    order_id: int = manager.start_data.get("order_id")
    session_factory = manager.middleware_data.get("session_factory")
    user_id = call.from_user.id

    try:
        scheduler.add_job(
            jobs.update_rotation_type,
            args=(
                bot,
                locale,
                session_factory,
                user_id,
                order_id,
                rotation_period,
                reload_type,
                config,
            ),
        )

        logger.info(f"Добавлена задача по смене ротации заказа {order_id}")
        if isinstance(call, types.CallbackQuery):
            await call.message.answer(locale.get("in-work-msg"))
        else:
            await call.answer(locale.get("in-work-msg"))

    except Exception as e:
        logger.exception(e)
        if isinstance(call, types.CallbackQuery):
            await call.message.answer(locale.get("error-msg"))
        else:
            await call.answer(locale.get("error-msg"))

    await manager.done()


rotation_period_window = Window(
    LocaleText("select-rotation-period"),
    Group(
        Button(LocaleText("five_minutes"), id="5", on_click=set_ip_change_period),
        Button(LocaleText("ten_minutes"), id="10", on_click=set_ip_change_period),
        Button(
            LocaleText("twenty_minutes"),
            id="20",
            on_click=set_ip_change_period,
        ),
        Button(LocaleText("one_hour"), id="60", on_click=set_ip_change_period),
        Button(LocaleText("by_link"), id="0", on_click=set_ip_change_period),
        Button(
            LocaleText("custom-option"),
            id="your_option",
            on_click=select_custom_period,
        ),
        width=2,
    ),
    Cancel(LocaleText("back-btn")),
    state=IpChangePeriodSG.select_ip_change_period,
)

custom_rotation_period_window = Window(
    LocaleText("select-ip-address"),
    TextInput("customperiodinp", int, on_success=set_ip_change_period),
    Back(LocaleText("back-btn")),
    Cancel(LocaleText("cancel-btn")),
    state=IpChangePeriodSG.select_custom_period,
)

rotation_period_dialog = Dialog(rotation_period_window, custom_rotation_period_window)


async def start_rotation_period_change(
    message: types.Message, widget: Any, manager: DialogManager
):
    if manager.start_data:
        order_id: int = manager.start_data.get("order_id")
    else:
        order_id: int = manager.dialog_data.get("order_id")

    await manager.start(
        IpChangePeriodSG.select_ip_change_period, {"order_id": order_id}
    )
